﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Xml;
using System.Collections;

namespace GenerateProtocol.Helper
{
    public static class XMLHelper
    {
        public static Hashtable MXmlSerializerList = Hashtable.Synchronized(new Hashtable());

        public static string Object2Xml(object o, Type type, bool addUtf8Header = false, bool isRemoveNamespaces = false)
        {
            try
            {
                string result = "";
                Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
                XmlSerializer xmlSerializer = null;
                if (!MXmlSerializerList.Contains(type))
                {
                    xmlSerializer = new XmlSerializer(type);
                    lock (MXmlSerializerList.SyncRoot)
                    {
                        MXmlSerializerList[type] = xmlSerializer;
                    }
                }
                else
                {
                    xmlSerializer = (XmlSerializer)MXmlSerializerList[type];
                }

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
                    xmlWriterSettings.Indent = true;
                    xmlWriterSettings.IndentChars = "    ";
                    xmlWriterSettings.NewLineChars = "\r\n";
                    xmlWriterSettings.Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
                    xmlWriterSettings.Indent = true;
                    if (isRemoveNamespaces)
                    {
                        XmlSerializerNamespaces xmlSerializerNamespaces = new XmlSerializerNamespaces();
                        xmlSerializerNamespaces.Add(string.Empty, string.Empty);
                        if (addUtf8Header)
                        {
                            using XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings);
                            xmlSerializer.Serialize(xmlWriter, o, xmlSerializerNamespaces);
                            xmlWriter.Close();
                        }
                        else
                        {
                            xmlSerializer.Serialize(memoryStream, o, xmlSerializerNamespaces);
                        }
                    }
                    else if (addUtf8Header)
                    {
                        using XmlWriter xmlWriter2 = XmlWriter.Create(memoryStream, xmlWriterSettings);
                        xmlSerializer.Serialize(xmlWriter2, o);
                        xmlWriter2.Close();
                    }
                    else
                    {
                        xmlSerializer.Serialize(memoryStream, o);
                    }

                    result = encoding.GetString(memoryStream.ToArray());
                    memoryStream.Dispose();
                }

                return result;
            }
            catch (Exception innerException)
            {
                throw new Exception("Serialize object to XML failed.", innerException);
            }
        }
    }
}
